package org.ruoyi.dhuman.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.dhuman.domain.bo.DhumanPptBo;
import org.ruoyi.dhuman.domain.vo.DhumanPptJobVo;
import org.ruoyi.dhuman.domain.vo.DhumanPptVo;
import org.ruoyi.dhuman.domain.vo.SubVideoRequestVo;
import org.ruoyi.dhuman.domain.vo.TTSRequestVo;
import org.ruoyi.dhuman.service.DhumanJobService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数字人讲解PPT任务
 *
 * @author wangliang
 * @date 2023-03-01
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/dhumanJob")
public class DhumanJobController {

	private final DhumanJobService dhumanPptService;

	/**
	 * 查询任务列表
	 */
	@GetMapping("/list")
	public R<TableDataInfo<DhumanPptJobVo>> list(PageQuery pageQuery) {
		DhumanPptBo bo = new DhumanPptBo();
		TableDataInfo<DhumanPptJobVo> result = dhumanPptService.selectAllocatedList(bo, pageQuery);
		return R.ok(result);
	}
	/**
	 * 以文件形式上传ppt
	 */
	@PostMapping("/uploadPPT")
	public R<DhumanPptVo> uploadPPT(MultipartFile file, HttpServletRequest request) {
		return dhumanPptService.uploadAndSavePPT(file);
	}

	/**
	 * 从已经生成的PPT中选择一张PPT
	 */
	@GetMapping("/selectPPT/{id}")
	public R<DhumanPptVo> selectPPT(@PathVariable String id) {
		return dhumanPptService.selectPPTFromPPTModule(id);
	}

	/**
	 * 加载 PPT 任务
	 */
	@GetMapping("/loadPPTJob/{id}")
	public R<DhumanPptVo> loadPPTJob(@PathVariable long id) {
		return dhumanPptService.loadPPTJob(id);
	}

	/**
	 * 复制 PPT 任务
	 */
	@GetMapping("/copyPPTJob/{id}")
	public R<DhumanPptVo> copyPPTJob(@PathVariable long id) {
		return dhumanPptService.copyPPTJob(id);
	}

	/**
	 * 试听语音
	 *
	 * id：子PPTid
	 * copyText： 文案
	 *
	 * ttsExpression：页面元素表达式，用于描述语音合成，表达式中的字段如下
	 * 	String voice_name; @JsonProperty(value = "voice_name")
	 * 	Integer with_caption; 是否返回时间戳，默认0 （0：否；1：是）
	 * 	String caption_type; 返回时间戳格式：tl 普通时间戳格式 tlx因素级时间戳格式
	 * 	String format; 默认MP3，可选:MP3/WAV
	 * 	Integer sample_rate; 音频采样率，默认44100，可选:8000/16000/24000/44100
	 * 	Float speed; 速度，默认1.0，可选区间:0.0-2.0
	 * 	Float pitch; 音调，默认1.0，可选区间:0.0-2.0
	 */
	@PostMapping("/genTTS")
	public R auditionTTS(@RequestBody @Valid TTSRequestVo vo) {
		return dhumanPptService.genTTS(vo);
	}

	/**
	 * 预览
	 */
	@PostMapping("/preview/{pptId}")
	public R<DhumanPptVo> preview(@PathVariable Long pptId) {
		return dhumanPptService.preview(pptId);
	}

	/**
	 * 合成视频
	 */
	@PostMapping("/genVideo/{pptId}")
	public R<DhumanPptVo> genVideo(@PathVariable Long pptId) {
		return dhumanPptService.genVideo(pptId);
	}

	/**
	 * 保存子PPT的表达式
	 *
	 * id：子PPTid
	 * copyText： 文案
	 *
	 * ttsExpression：页面元素表达式，用于描述语音合成，表达式中的字段如下
	 * 	String voice_name; @JsonProperty(value = "voice_name")
	 * 	Integer with_caption; 是否返回时间戳，默认0 （0：否；1：是）
	 * 	String caption_type; 返回时间戳格式：tl 普通时间戳格式 tlx因素级时间戳格式
	 * 	String format; 默认MP3，可选:MP3/WAV
	 * 	Integer sample_rate; 音频采样率，默认44100，可选:8000/16000/24000/44100
	 * 	Float speed; 速度，默认1.0，可选区间:0.0-2.0
	 * 	Float pitch; 音调，默认1.0，可选区间:0.0-2.0
	 *
	 * dhumanExpression：页面元素表达式，用于描述数字人讲解PPT，表达式中的字段如下
	 *  String bgUrl; 背景链接
	 * 	Float bgX; 背景位置 x
	 * 	Float bgY; 背景位置 y
	 * 	Integer bgW; 背景宽度
	 * 	Integer bgH; 背景高度
	 *
	 *  String pptUrl; PPT链接
	 * 	Float pptX; PPT位置 x
	 * 	Float pptY; PPT位置 y
	 * 	Integer pptW; PPT宽度
	 * 	Integer pptH; PPT高度
	 *
	 * 	// 数字人
	 *  Long dhumanId; 数字人Id
	 *  String dhumanUrl; 数字人图像链接
	 * 	Float dhumanX;	数字人位置 x
	 * 	Float dhumanY;  数字人位置 y
	 * 	Integer dhumanW; 数字人宽度
	 * 	Integer dhumanH; 数字人高度
	 *
	 *  // 字幕
	 *  boolean hasSubtitle; 是否显示字幕
	 * 	Float subtitleX; 字幕位置 x
	 * 	Float subtitleY; 字幕位置 y
	 * 	Integer subtitleW; 字幕宽度
	 * 	Integer subtitleH; 字幕高度
	 *
	 * 	// 公共参数
	 * 	Integer delayedSeconds; 当前画面播放完成后延后多少秒播放下一画面
	 */
	@PostMapping("/v1/saveSubVideoExpression")
	public R<DhumanPptVo> saveSubVideoExpressionVo(@RequestBody @Valid SubVideoRequestVo vo) {
		return dhumanPptService.saveSubVideoExpressionVoWithV1(vo);
	}

	/**
	 * 批量保存PPT列表
	 */
	@PostMapping("/v1/saveListWithV1/{pptId}")
	public R<DhumanPptVo> saveListWithV1(@PathVariable Long pptId, @RequestBody @Valid List<SubVideoRequestVo> voList) {
		return dhumanPptService.saveListWithV1(pptId, voList);
	}

	/**
	 * 重新排序子PPT列表
	 */
	@PostMapping("/v1/reSortListWithV1/{pptId}")
	public R<DhumanPptVo> reSortListWithV1(@PathVariable Long pptId, @RequestBody @Valid List<SubVideoRequestVo> voList) {
		return dhumanPptService.reSortListWithV1(pptId, voList);
	}

	/**
	 * 获取中文的拼音
	 */
	@PostMapping("/pinyin")
	public R reSortListWithV1(@RequestBody String chinese) {
		if (StringUtils.isEmpty(chinese)) {
			return R.ok();
		}

		List<Map<String, Object>> retList = new ArrayList<>();
		for (char c : chinese.toCharArray()) {
			Map<String, Object> item = new HashMap<>();
			item.put("chat", c);
			String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c);
			if (pinyinArray != null && pinyinArray.length > 0) {
				item.put("pinyin", pinyinArray);
			} else {
				item.put("chat", c);
			}
			retList.add(item);
		}

		return R.ok(retList);
	}
}
